package org.byqh.dqeai.controller;

import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.commons.lang3.StringUtils;
import org.byqh.dqeai.common.Json;
import org.byqh.dqeai.dto.SysAppModuleDTO;
import org.byqh.dqeai.dto.common.InsertListAndSortDto;
import org.byqh.dqeai.entity.SysAppModule;
import org.byqh.dqeai.entity.proxy.SysAppModuleProxy;
import org.byqh.dqeai.enums.SystemEnum;
import org.byqh.dqeai.util.SpringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.LinkedList;
import java.util.List;

@RestController
@RequestMapping("/appmodule")
@Tag(name = "系统[SysAppModule] - 应用模块管理")
public class SysAppModuleController extends BaseController<SysAppModule, SysAppModuleProxy> {
    @Override
    @GetMapping(value = "/get/{id}")
    public Json<SysAppModule> get(String id) {
        return super.get(id);
    }

    @Override
    @PutMapping(value = "/put")
    public Json<Boolean> put(SysAppModule dto) {
        return super.put(dto);
    }

    @Override
    @PostMapping(value = "/post")
    public Json<Boolean> post(SysAppModule dto) {
        return super.post(dto);
    }

    /**
     * 获取某一个具体模块对象信息
     */
    @GetMapping(value = "/{appId}")
    public Json<List<SysAppModuleDTO>> get2(@PathVariable String appId) {
        if (StringUtils.isBlank(appId)) {
            return Json.errorT(SystemEnum.USER_OPREATION_ENUM.PARAMS_NULL.getValue());
        }

        return listImpl(SysAppModuleDTO.class, query -> {
            return query.where(r -> r.appId().eq(appId));
        });
    }

    /**
     * 新增某一个具体模块对象信息
     */
    @PostMapping(value = "/")
    public Json<Boolean> post(@RequestBody SysAppModuleDTO dto) {
        var now = LocalDateTime.now();

        dto.setUpdateDate(now);
        dto.setCreateDate(now);

        return easyEntityQuery.insertable(dto).executeRows() > 0 ? Json.success() : Json.error();
    }

    /**
     * 修改某一个具体模块对象信息
     */
    @PutMapping(value = "/")
    public Json<Boolean> put(@RequestBody SysAppModuleDTO dto) {
        if (dto == null || StringUtils.isBlank(dto.getAppId()) || StringUtils.isBlank(dto.getModuleId())) {
            return Json.errorT(SystemEnum.USER_OPREATION_ENUM.PARAMS_NULL.getValue());
        }

        var one = this.getEntityQueryable()
                .where(s -> s.appId().eq(dto.getAppId().trim()))
                .where(s -> s.moduleId().eq(dto.getModuleId().trim()))
                .firstOrNull();

        if (one == null) {
            return Json.error("不存在要更改的数据", false, HttpStatus.OK.value());
        }

        BeanUtils.copyProperties(dto, one, SpringUtils.getNullPropertyNames(dto));

        return this.save(one);
    }

    /**
     * 删除某一个具体模块对象信息
     */
    @DeleteMapping(value = "/")
    public Json<Boolean> delete(@RequestParam String appId, @RequestParam String moduleId) {
        if (StringUtils.isBlank(appId) || StringUtils.isBlank(moduleId)) {
            return Json.errorT("参数不能为空!");
        }

        String sql = """
                    begin
                      DELETE EAI_SYS_ROLE_MODULE
                       WHERE MODULE_ID IN
                             (SELECT MODULE_ID
                                FROM SYS_APP_MODULE
                               WHERE APP_ID = #{appId}
                                 AND MODULE_ID IN
                                     (select MODULE_ID
                                        FROM SYS_APP_MODULE
                                       WHERE APP_ID = #{appId}
                                       start with MODULE_ID = #{moduleId}
                                      connect by prior MODULE_ID = PARENT_MODULE_ID));
                
                      DELETE SYS_APP_MODULE
                       WHERE APP_ID = #{appId}
                         AND MODULE_ID IN
                             (select MODULE_ID
                                FROM SYS_APP_MODULE
                               WHERE APP_ID = #{appId}
                               start with MODULE_ID = #{moduleId}
                              connect by prior MODULE_ID = PARENT_MODULE_ID);
                    end;
                """;

        sql = sql.replace("#{appId}", String.format("'%s'", appId))
                .replace("#{moduleId}", String.format("'%s'", moduleId));

        easyQueryClient.sqlExecute(sql);

        return Json.success();
    }

    /**
     * 查询模块对象信息列表
     */
    @GetMapping(value = "/list")
    public Json<List<SysAppModule>> list(
            @RequestParam(required = false, defaultValue = "") String appId,
            @RequestParam(required = false, defaultValue = "") String moduleId) {

        var query = this.getEntityQueryable();

        if (!StringUtils.isBlank(appId)) {
            query = query.where(r -> r.appId().eq(appId));
        }

        if (!StringUtils.isBlank(moduleId)) {
            query = query.where(r -> r.moduleId().eq(moduleId));
        }

        query.orderBy(r -> r.moduleSeq().asc());

        return Json.success(query.toList());
    }

    /**
     * 分页查询数据
     */
    @PostMapping(value = "/listAll")
    public Json<List<SysAppModule>> listAll(@RequestBody(required = false) SysAppModuleDTO dto) {
        var query = this.getEntityQueryable();

        if (dto != null) {
            if (!StringUtils.isBlank(dto.getUserId())) {
                String in_query = String.format(
                        "SELECT DISTINCT MODULE_ID\n" +
                                "  FROM SYS_APP_MODULE\n" +
                                " start with MODULE_ID IN (SELECT DISTINCT B.MODULE_ID\n" +
                                "    FROM EAI_SYS_USER_ROLE A, EAI_SYS_ROLE_MODULE B\n" +
                                "   WHERE A.USER_ID = '%s'\n" +
                                "     AND A.ROLE_ID = B.ROLE_ID)\n" +
                                "connect by NOCYCLE prior PARENT_MODULE_ID = MODULE_ID", dto.getUserId());

                query.where(o -> o.moduleId().in(easyQueryClient.queryable(in_query, String.class)));
            } else if (!StringUtils.isBlank(dto.getRoleId())) {
                String in_query = String.format(
                        "SELECT DISTINCT MODULE_ID\n" +
                                "  FROM SYS_APP_MODULE\n" +
                                " start with MODULE_ID IN (SELECT DISTINCT MODULE_ID\n" +
                                "   FROM EAI_SYS_ROLE_MODULE A\n" +
                                "   WHERE A.ROLE_ID = '%s'\n)" +
                                "connect by NOCYCLE prior PARENT_MODULE_ID = MODULE_ID", dto.getRoleId());

                query.where(o -> o.moduleId().in(easyQueryClient.queryable(in_query, String.class)));
            }
        }

        query.orderBy(e -> e.moduleSeq());

        return Json.success(query.toList());
    }

    /**
     * 查询用户关联模块
     */
    @GetMapping(value = "/listByAppIdAndUserId")
    public Json<List<SysAppModuleDTO>> listByAppIdAndUserId(
            @RequestParam(required = false, defaultValue = "") String appId,
            @RequestParam(required = false, defaultValue = "") String userId
    ) {
        if (StringUtils.isBlank(appId) || StringUtils.isBlank(userId)) {
            return Json.errorT(SystemEnum.USER_OPREATION_ENUM.PARAMS_NULL.getValue());
        }

        String sql = String.format("""
                 select distinct *
                        from SYS_APP_MODULE t
                            connect by NOCYCLE prior parent_module_id = module_id
                        start with app_id = '%s'
                               and module_id in
                                 (select module_id
                            from EAI_SYS_ROLE_MODULE
                            where role_id in (select role_id
                            from EAI_SYS_USER_ROLE
                            where user_id = '%s'))
                            order by module_seq
                """, appId, userId);

        return Json.success(this.getEntityQueryableBySql(sql).selectAutoInclude(SysAppModuleDTO.class).toList());
    }

    /**
     * 批量插入模块, 并更新排序
     */
    @PostMapping(value = "/InsertListAndSort")
    public Json<Boolean> InsertListAndSort(@RequestBody InsertListAndSortDto<SysAppModuleDTO> dto) {
        if (dto.getList() != null) {
            for (SysAppModuleDTO one : dto.getList()) {
                this.post(one);
            }
        }

        if (dto.getSort() != null) {
            List<SysAppModule> list = new LinkedList<>();

            for (var kv : dto.getSort()) {
                SysAppModule one = new SysAppModule();
                one.setModuleId(kv.getKey());
                one.setModuleSeq(kv.getValue().shortValue());
            }

            easyEntityQuery.updatable(list)
                    .setColumns(s -> s.moduleSeq())
                    .executeRows();
        }

        return Json.success(true);
    }
}